package com.linkivr;

import java.sql.ResultSet;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

class UpThread extends Thread {
	private String name = "";

	DBManager[] dbman = new DBManager[2];
	int retrycount = 0;
	int intervaltime = 0;
	boolean initpbxFlag = true;
	int[] hmss = new int[6];

	int maxReadCount = 30;
	int maxCallCount = 60;
	String tabConfig = "";
	String tabService = "";
	String tabCall = "";

	public UpThread(String name) {
		this.name = name;
		this.maxReadCount = G.appConf.maxReadCount;
		this.maxCallCount = G.appConf.maxCallCount;
		this.tabConfig = G.appConf.tabConfig;
		this.tabService = G.appConf.tabService;
		this.tabCall = G.appConf.tabCall;
	}

	public boolean validTime(int hms, int[] hmss) {
		boolean result = false;
		int count = (hmss.length / 2);

		for (int i = 0; i < count; i++) {
			if (hms > hmss[i * 2] && hms < hmss[i * 2 + 1]) {
				result = true;
				break;
			}
		}
		return result;
	}

	public int getHMS(String strDate) throws ParseException {
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		Date dt = df.parse(strDate);

		Calendar cal = Calendar.getInstance();
		cal.setTime(dt);

		return cal.get(Calendar.HOUR_OF_DAY) * 3600 + cal.get(Calendar.MINUTE) * 60 + cal.get(Calendar.SECOND);

	}

	public int getNowHMS() {
		Calendar cal = Calendar.getInstance();
		return cal.get(Calendar.HOUR_OF_DAY) * 3600 + cal.get(Calendar.MINUTE) * 60 + cal.get(Calendar.SECOND);
	}

	// create two db connections
	public void connDB() throws Exception {
		DBConf[] dbconf = G.appConf.upDB;
		for (int i = 0; i < 2; i++) {
			GL.info("begin create  db" + i + " connection");
			dbman[i] = new DBManager(dbconf[i].driver, dbconf[i].url, dbconf[i].user, dbconf[i].passwd);
			GL.info("end create db" + i + " connection");
		}
	}

	// 1.check config
	public boolean checkConfig() throws Exception {

		String sql = "select begintime1,endtime1, begintime2,endtime2, begintime3,endtime3,retrycount,update_flag,intervaltime from "
				+ tabConfig;
		GL.info(sql);
		ResultSet newrs = dbman[0].executeQuery(sql);

		if ((newrs == null) || (newrs.next() == false)) {
			return false;
		}
		int update_flag = newrs.getInt("update_flag");
		GL.info("update_flag=" + update_flag);

		if (initpbxFlag || (update_flag != 0)) {
			retrycount = newrs.getInt("retrycount");
			intervaltime = newrs.getInt("intervaltime");
			String[] strDate = new String[6];
			strDate[0] = newrs.getString("begintime1");
			strDate[1] = newrs.getString("endtime1");
			strDate[2] = newrs.getString("begintime2");
			strDate[3] = newrs.getString("endtime2");
			strDate[4] = newrs.getString("begintime3");
			strDate[5] = newrs.getString("endtime3");

			for (int i = 0; i < 6; i++) {
				hmss[i] = getHMS(strDate[i]);
			}
			sql = "update " + tabConfig + " set update_flag='0' ";
			GL.info(sql);
			int actlines = dbman[0].executeUpdate(sql);
			initpbxFlag = false;
			GL.info("update table: " + actlines + " lines effect");
		}

		int hms = getNowHMS();
		boolean vt = validTime(hms, hmss);
		if (vt == false) {
			GL.info("now is not work time ,continue loop!");
			return false;
		}
		return true;

	}

	// 2.check tabCall free or not,max maxCallCount
	public boolean checkSendCount() throws Exception {
		String sql = "select count(*) as count from " + tabCall;
		GL.info(sql);
		ResultSet newrs = dbman[1].executeQuery(sql);

		if ((newrs == null) || (newrs.next() == false)) {
			return false;
		}
		int callcount = newrs.getInt("count");
		GL.info("count of curr call table is: " + callcount);
		if (callcount > maxCallCount) {
			GL.info("count of curr call table is too much, wait continue! ");
			return false;
		}
		return true;
	}

	// 3.select from tabService, insert and update
	public boolean transmitData() throws Exception {
		String sql;
		ResultSet newrs;
		int actlines;

		sql = "select pbxSend_Code,user_phone,flow_file,get_count,get_flag from " + tabService
				+ " where tel_status is null or tel_status='0' and   get_flag='0' and get_count<" + retrycount
				+ " and (NOW() -get_time)> " + intervaltime + " order by get_count limit 0," + maxReadCount;

		GL.info(sql);
		newrs = dbman[0].executeQuery(sql);

		if ((newrs == null)) {
			GL.info("no row affect ,continue loop!");
			return false;
		}

		List<CallInfo> callList = new ArrayList<CallInfo>();//

		while (newrs.next()) {

			CallInfo info = new CallInfo();
			info.pbxSend_Code = newrs.getString("pbxSend_Code");
			info.user_phone = newrs.getString("user_phone");
			info.flow_file = newrs.getString("flow_file");
			callList.add(info);
		}
		// 4.insert

		Iterator<CallInfo> it = callList.iterator();
		while (it.hasNext()) {
			CallInfo ci = it.next();

			sql = "insert into " + tabCall + "(callermobile,calledmobile,displaymobile,ordertype,songid,leaveword,"
					+ "dialtime,dialcount,flag,companyid,subflow,accessno,linkid,bs_i3_rowid,workflowname,autodelflag)"
					+ " values('10109999','" + ci.user_phone + "','10109999','0','',''," + "now(),'5','0','1','"
					+ ci.flow_file + "','10109999','1','" + ci.pbxSend_Code + "','" + tabService + "','2')  ";
			GL.info(sql);
			actlines = dbman[1].executeUpdate(sql);
			GL.info("insert table: " + actlines + " lines effect");

			// 5. update tabService
			sql = "update " + tabService
					+ " set tel_status='-11', get_flag='1',get_count=get_count+1,get_time=now() where pbxSend_Code= '"
					+ ci.pbxSend_Code + "'";
			GL.info(sql);
			actlines = dbman[0].executeUpdate(sql);
			GL.info("update table: " + actlines + " lines effect");

		}
		return true;
	}

	@Override
	public void run() {
		// ----
		GL.info(name + " run now!!");

		boolean connected = false;

		while (G.appConf.uprun == 1) {
			try {

				Thread.sleep(G.appConf.upcycle);
				GL.info("begin new work loop");

				// 0.create db connection
				if (!connected) {
					connDB();
					connected = true;
				}

				// 1.check update time limit
				if (!checkConfig()) {
					continue;
				}

				// 2.check tabCall table free or not,max 30
				if (!checkSendCount()) {
					continue;
				}

				// 3.select from tabService, insert and update
				if (!transmitData()) {
					continue;
				}

			} catch (Exception e) {
				connected = false;
				GL.logException(e);

				for (int i = 0; i < 2; i++) {
					if (dbman[i] != null) {
						dbman[i].close();
						dbman[i] = null;
					}
				}

			}
		}

	}
}
